package com.starbaba.core.hibernate;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang.reflect.FieldUtils;
import org.hibernate.transform.AliasToBeanResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 记录行转换为VO对象
 *
 * @Copyright: Copyright (c) 2006
 * @Company: Revenco Tech Ltd.
 * @anthor chenminhui<chenminhui@revenco.com>
 * @since 2013-10-23 下午02:51:14
 * @version V1.0
 */
@SuppressWarnings({"serial", "unchecked","rawtypes"})
public class ExtAliasToBeanResultTransformer extends AliasToBeanResultTransformer {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	private final Class returnVoClass;
	
	public ExtAliasToBeanResultTransformer(Class resultClass) {
		super(resultClass);
		
		returnVoClass = resultClass;
	}

	/** 
	 * 把每一行记录字段值，赋给VO属性
	 * 
	 * @see org.hibernate.transform.AliasToBeanResultTransformer#transformTuple(java.lang.Object[], java.lang.String[])
	 */
	@Override
	public Object transformTuple(Object[] tuple, String[] aliases) {
		
		String[] newAliases = new String[aliases.length];
		for(int i = 0; i < aliases.length; i++) {
			String ali = aliases[i];
			//1. 把字段名称转成小写，如：MENUID --> menuid
			ali = StringUtils.lowerCase(ali);
			
			//2. 把字段名称中"_"去掉，并把接下来的字符转成大写，例如：create_date --> createDate
			ali = capitalize(ali, '_');
			newAliases[i] = ali;
		}
		
		//过滤掉分页时使用的rownum字段值
		Object[] filteredField = filterField(new Object[]{newAliases, tuple}, new String[]{"rownum"});
		newAliases = (String[]) filteredField[0];
		tuple = (Object[]) filteredField[1];
		
		
		/*
		 * 4. 转换类型，
		 * 	把java.sql.Date转换为java.util.Date; 
		 *  把java.math.BigDecimal转换为java.lang.Short或者java.lang.Integer或者java.lang.Long或者java.lang.Float或者java.lang.Double
		 */
		Object[] newTuple = new Object[tuple.length];
		for(int i = 0; i < tuple.length; i++) {
			Object t = tuple[i];
		
			if(t instanceof java.sql.Date) {
				newTuple[i] = new Date(((java.sql.Date) t).getTime());
			} else if(t instanceof java.math.BigDecimal){
				java.math.BigDecimal temDecimal = (java.math.BigDecimal) t;
				
				Field field = FieldUtils.getField(returnVoClass, newAliases[i], true);
				if(field == null) {
					logger.warn("Could not found field named '" + newAliases[i] + "'");
					continue;
				}
				
				Class fieldClass = field.getType();
//				logger.info("returnVoClass=" + returnVoClass + ",index=" + index + ",newAliases[index]=" + newAliases[index]);
				
				if(fieldClass.isAssignableFrom(java.lang.Short.class)) {
					newTuple[i] = temDecimal.shortValue();
				} else if(fieldClass.isAssignableFrom(java.lang.Integer.class)) {
					newTuple[i] = temDecimal.intValue();
				} else if(fieldClass.isAssignableFrom(java.lang.Long.class)) {
					newTuple[i] = temDecimal.longValue();
				} else if(fieldClass.isAssignableFrom(java.lang.Float.class)) {
					newTuple[i] = temDecimal.floatValue();
				} else if(fieldClass.isAssignableFrom(java.lang.Double.class)) {
					newTuple[i] = temDecimal.doubleValue();
				} else {
					newTuple[i] = t;
				}
			} else {
				newTuple[i] = t;
			}
		}
		
//		logger.info("aliases = " + StringUtils.join(newAliases, "\n"));
		
		return super.transformTuple(newTuple, newAliases);
	}

	/**
	 * 把字段名称中"_"去掉，并把接下来的字符转成大写，例如：create_date --> createDate
	 * 
	 * @param str 待转换的字符串
	 * @param delimiter 分隔符
	 * @return String 转换后的字符串
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2013-10-22 下午04:50:37
	 * @version V1.0
	 */
	public static String capitalize(String str, char delimiter) {
		StringBuffer result = new StringBuffer();
		char[] chars = str.toCharArray();
		
		boolean needUpperCase = false; 
		for(char c: chars) {
			if(c == delimiter) {
				needUpperCase = true;
			} else if(needUpperCase) {
				result.append(StringUtils.upperCase(String.valueOf(c)));
				needUpperCase = false;
			} else {
				result.append(String.valueOf(c));
			}
		}
		return result.toString();
	}
	
	/**
	 * 过滤字段
	 * 
	 * @param values 待过滤值，包括：aliases和tuple
	 * @param needFilter 需要过滤字段
	 * @return Object[] 过滤后的值
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2013-10-23 下午03:25:04
	 * @version V1.0
	 */
	private static Object[] filterField(Object[] values, String[] needFilter) {
		String[] aliases = (String[]) values[0];
		Object[] tuple = (Object[]) values[1];
		
		List temTuple = new ArrayList();
		List<String> temAliases = new ArrayList<String>();
		for(int i = 0; i < aliases.length; i++) {
			String ali = aliases[i];
			
			if(!ArrayUtils.contains(needFilter, ali)) {
				temTuple.add(tuple[i]);
				temAliases.add(aliases[i]);
			} else {
//				System.err.println("ignor field '" + ali + "'");
			}
		}
		
		values = new Object[]{temAliases.toArray(new String[0]), temTuple.toArray(new Object[0])};
		
		temAliases.clear();
		temTuple.clear();
		
		return values;
	}
	
	/**
	 * @param args
	 *
	 * @Copyright: Copyright (c) 2006
	 * @Company: Revenco Tech Ltd.
	 * @anthor chenminhui<chenminhui@revenco.com>
	 * @since 2013-10-22 下午04:30:47
	 * @version V1.0
	 */
	public static void main(String[] args) {
		String str = "create_date_abc";
		System.out.println(WordUtils.capitalize(str, new char[]{'_'}));
	}

}
